#!/usr/bin/env node

/**
 * Module dependencies.
 */
const { Command } = require('commander')
const program = new Command()
const cp = require('child_process')
const util = require('util')
const exec = util.promisify(cp.exec)
const path = require('path')
const chalk = require('chalk')
const autoCreate = require('./lib/autoCreate')
const { version } = require('./package.json')
const ImgMin = require('./lib/imgMin.js')
const lessCompile = require('./lib/lessCompile.js')
const autoUploadMini = require('./lib/autoUploadMini.js')
const autoJenkis = require('./lib/autoJenkis')
const autoHusky = require('./lib/autoHusky')
const autoCompress = require('./lib/autoCompress')
// const autoCommitizen = require('./lib/autoCommitizen')
const copy = require('shelljs').cp
const {
  format_time,
  copyToClipboard,
  successLog,
  errorLog,
  log,
  showLoading,
  hideLoading,
} = require('./utils.js')

//shell.cp('-R', '-dir', 'outdir');
let environmental = 'test',
  name = ''
let packageJson = {}

function resolve(pathname) {
  return path.resolve(process.cwd(), pathname)
}

try {
  packageJson = require(resolve('package.json'))
  name = packageJson.name
} catch (error) {}

program
  .version(`v${version}`)
  .description(`这是前端项目组一个命令行工具 版本v${version}`)
  .option('-project,--project [name]', 'build you develop project name')
  .option('-token,--apitoken [apitoken]', 'send your api token')
  .option('-author,--author [name]', 'send your jenkins author')
  .option('-trigger,--triggerName [name]', 'send your triggerName')
  .option('-branch,--gitBranch [name]', 'send your gitBranch/tags')
  .option('-autotag,--autotag [name]', 'auto creat your tags')
  .option('-host,--host [name]', 'send your jenkis host')
  .option('-file,--file [name]', 'send your file')
  .option('-newfile,--newfile [name]', 'send your newfile')
  .option('-imgMin,--k')

program.on('--help', function () {
  console.log('')
  console.log('Examples:')
  console.log('  $ custom-help --help')
  console.log('  $ custom-help -h')
})
//111
// error on unknown commands
program
  .command('setup [env]')
  .description('run setup commands for all envs')
  .action(async function (env, options) {
    const mode = options.setup_mode || 'normal'
    env = env || 'all'
    console.log('setup for %s env(s) with %s mode', env, mode)
    environmental = env
    showLoading()
    try {
      //生成tagname
      if (program.autotag) {
        const tagName = `d${format_time(
          new Date().getTime(),
          'yyyyMMddhhmmss'
        )}`
        await exec(`git tag -a ${tagName} -m "${tagName}"`)
        await exec(`git push origin --tags`)
        program.gitTagName = `refs/tags/${tagName}`
        console.log('执行构建标签--->', program.gitTagName)
      }
      //目前只有测试和开发允许默认构建dev_branch分支
      if (env == 'test' || env == 'dev') {
        autoJenkis(program)
      }
      //如果是正式环境一定需要配置对应的分支或者tag
      if (env == 'build' && program.gitBranch && program.gitBranch !== 'xx') {
        autoJenkis(program)
      }
    } catch (error) {
      console.log('error--->', error)
    }
    hideLoading()
  })

// 仅仅打tag
program
  .command('git-tag [env]')
  .option('-t, --tag <tag>', 'set input tag')
  .description('set git tag for all envs')
  .action(async function (env, options) {
    // 生成tagname
    showLoading()
    try {
      const tagName =
        options.tag || `d${format_time(new Date().getTime(), 'yyyyMMddhhmmss')}`
      await exec(`git tag -a ${tagName} -m ${tagName}`)
      await exec(`git push origin --tags`)
      log('已生成tagName--->', tagName)
      const projectName = program.project || name
      let string = `${projectName}项目, 提测tagName为:${tagName} `
      copyToClipboard(string, () => {
        log('已经复制以下内容到剪切板')
        successLog(string)
      })
    } catch (error) {
      errorLog('error --->', error)
    }
    hideLoading()
  })

//替换文件
// error on unknown commands
program
  .command('auto-replace-file [env]')
  .description('run auto-replace-file for repalce file')
  .option('-outdir, --outdir <outdir>', 'set input outdir')
  .option('-inputdir, --inputdir <inputdir>', 'set input inputdir')
  .action(async function (env, options) {
    showLoading()
    try {
      const file = program.file || options.outdir || 'package.json'
      const newfile = program.newfile || options.inputdir || 'rf-package.json'
      // await exec(`cp -rf ${resolve(newfile)} ${resolve(file)}`)
      await copy('-rf', `${resolve(newfile)}`, `${resolve(file)}`)
      console.log('配置文件替换')
    } catch (error) {
      console.log('command push---->', error)
    }
    hideLoading()
  })

//构建项目
// error on unknown commands
program
  .command('push [env]')
  .option('-m, --message <message>', 'message')
  .option('-r, --replace <replace>', 'replace file')
  .option('-p, --push <push>', 'push file')
  .description('run push commands for all envs')
  .action(async function (env, options) {
    showLoading()
    try {
      const replace = options.replace
      const push = options.push
      const file = program.file || 'package.json'
      const newfile = program.newfile || 'rf-package.json'
      if (replace) {
        await exec(`cp -f ${resolve(newfile)} ${resolve(file)}`)
        console.log('配置文件替换')
      }
      console.log('代码提交中···')
      const tagName = `${format_time(
        new Date().getTime(),
        'yyyy-MM-dd+hh:mm:ss'
      )}`
      const message = options.message || `feat: ${tagName}`
      await exec(`git init`)
      await exec(`git add -A`)
      await exec(`git add .`)
      await exec(`git commit -m "${message}"`).catch((error) => {
        console.log('commit---->', error)
      })
      await exec(`git pull origin`)
      if (push) {
        await exec(`git push origin`)
        console.log('代码远程提交成功')
      } else {
        console.log('代码本地提交成功')
      }
    } catch (error) {
      console.log('command push---->', error)
    }
    hideLoading()
  })

//构建 autoCommitizen
// program
//   .command('cz [env]')
//   .option('-m, --message <message>', 'message')
//   .description('run cz commands for all evns')
//   .action(async function (env, option) {
//     autoCommitizen(option)
//   })

//serve
// error on unknown commands
//配置启动一个静态资源服务器
program
  .command('auto-serve [env]')
  .description('run auto-serve commands for all envs')
  .option('-p, --port <port>', 'Which exec port to use')
  .option('-d, --dir <dir>', 'Which exec dir to use')
  .action(async function (env, options) {
    showLoading()
    try {
      const port = options.port || '8009'
      const dir = options.dir || ''
      // console.log('options---->', options, env);
      console.log('exc---->', `anywhere -p ${port} -d ${dir}`)
      await exec(`anywhere -p ${port} -d ${dir}`)
    } catch (error) {
      console.log('auto-serve anywhere---->', error)
      console.log('如未安装anywhere请自行安装 npm i anywhere -g')
    }
    hideLoading()
  })

/**
 * @description: 自动生成文件方法  rf-cli create
 * @param {type} path 生成的文件名（如/xx/a.js）
 * @return {type} tempate 模板文件
 */
program
  .command('create')
  .description('run create template file commands')
  .action(async function (options) {
    try {
      autoCreate()
    } catch (error) {
      console.log(error)
    }
  })

/**
 * @description: 小程序自动上传  rf-cli uploadMini
 */

program
  .command('uploadMini')
  .description('run upload miniprogrammer commands')
  .action(async function (options) {
    try {
      autoUploadMini(options)
    } catch (error) {
      console.log(error)
    }
  })

//自动化构建格式化husky工程化
program
  .command('husky')
  .description('run husky your project commands')
  .action(async function (options) {
    try {
      autoHusky(options)
    } catch (error) {
      console.log(error)
    }
  })

//压缩文件为zip
program
  .command('compress [env]')
  .option('-f, --folder <folder>', 'set input folder')
  .option('-z, --zip <zip>', 'set input zip')
  .option('-l, --level <level>', 'set input level')
  .option('-s, --subdir <subdir>', 'set input subdir')
  .description('run compress commands for all envs')
  .action(async function (env, options) {
    autoCompress(options)
  })

// 图片压缩
ImgMin(program)

// less预编译
lessCompile(program)

program.parse(process.argv)
